
#include "coord.h"

#define COORD_DIM 3

#define COORD_X 0
#define COORD_Y 1
#define COORD_Z 2

#include <cmath>

Coord::Coord() {
   for(int i = 0; i < COORD_DIM; ++i) 
      data[i] = 0.0;
}

Coord::Coord(const Coord &aCopiar) {
   (*this) = aCopiar;
}

Coord::Coord(float x, float y, float z) {
   data[COORD_X] = x;
   data[COORD_Y] = y;
   data[COORD_Z] = z;
}

Coord::Coord(const float *f) {
   (*this) = f;
}

Coord& Coord::operator=(const float *f) {
   for(int i = 0; i < COORD_DIM; ++i)
      data[i] = f[i];

   return (*this);
}

Coord& Coord::operator=(const Coord &aCopiar) {
   for(int i = 0; i < COORD_DIM; ++i)
      data[i] = aCopiar.data[i];

   return (*this);
}

void Coord::set(float x, float y, float z) {
   data[COORD_X] = x;
   data[COORD_Y] = y;
   data[COORD_Z] = z;
}

Coord::operator const float*() const {
   return data;
}

void Coord::operator+=(const Coord &b) {
   for(int i = 0; i < COORD_DIM; ++i) 
      data[i] += b.data[i];
}

Coord Coord::operator+(const Coord &b) const {
   Coord sum(*this);
   sum += b;
   return sum;
}

Coord Coord::operator-(const Coord &b) const {
   return (*this) + (b * (-1));
}

Coord Coord::operator*(const float e) const {
   Coord escalado(*this);

   for(int i = 0; i < COORD_DIM; ++i) 
      escalado.data[i] *= e;

   return escalado;
}

float Coord::operator*(const Coord& e) const {
   float acum = 0;
   for(int i = 0; i < COORD_DIM; ++i) 
      acum += data[i] * e.data[i];
      
   return acum;
}


void Coord::operator*=(const float e) {
   for(int i = 0; i < COORD_DIM; ++i) 
      data[i] *= e;
}

Coord Coord::normalizar() const {
   float norma = 0.0;
   for(int i = 0; i < COORD_DIM; ++i) 
      norma += data[i] * data[i];

   return (*this) * (1.0/sqrt(norma));
}

Coord Coord::cross(const Coord &c) const {
   return Coord( y()*c.z() - z()*c.y(),
         z()*c.x() - x()*c.z(),
         x()*c.y() - y()*c.x());
}


Coord operator*(const float e, const Coord &c) {
   return c * e;
}

